#pragma once

#include "SPD3D11Prerequisite.h"

///----------------------------------------------------------------
// SPTimer
///----------------------------------------------------------------
namespace SP
{
	// From DXUTtimer
	class DLL_EXPORT SPTimer
	{
	public:
		SPTimer();
		void				Reset(); // resets the timer
		void				Start(); // starts the timer
		void				Stop();  // stop (or pause) the timer
		void				Advance(); // advance the timer by 0.1 seconds
		double			GetAbsoluteTime(); // get the absolute system time
		double			GetTime(); // get the current time
		float				GetElapsedTime(); // get the time that elapsed between Get*ElapsedTime() calls
		void				GetTimeValues( double* pfTime, double* pfAbsoluteTime, float* pfElapsedTime ); // get all time values at once
		bool				IsStopped(); // returns true if timer stopped

		// Limit the current thread to one processor (the current one). This ensures that timing code runs
		// on only one processor, and will not suffer any ill effects from power management.
		void				LimitThreadAffinityToCurrentProc();

	protected:
		LARGE_INTEGER   GetAdjustedCurrentTime();

		bool m_bUsingQPF;
		bool m_bTimerStopped;
		LONGLONG m_llQPFTicksPerSec;

		LONGLONG m_llStopTime;
		LONGLONG m_llLastElapsedTime;
		LONGLONG m_llBaseTime;
	};
}

// SPFileBuffer
namespace SP
{

}

///----------------------------------------------------------------
// SPDistributionClass
///----------------------------------------------------------------
namespace SP
{
	//----------------------------------------------------------
	DLL_EXPORT float SPRPresent();

	//----------------------------------------------------------
	class DLL_EXPORT SPDistributionFloat
	{
	public:
		SPDistributionFloat(){}
		virtual FLOAT CalcuValue() = 0;
		virtual void GetFileBufferInfo( UINT* type, FLOAT* constant, FLOAT* max, FLOAT* min) = 0;

		virtual SPDistributionFloat* SpawnInstance() = 0;
	};


	//----------------------------------------------------------
	class DLL_EXPORT SPDistributionFloatConstant : public SPDistributionFloat
	{
	public:
		SPDistributionFloatConstant( FLOAT init );
		virtual FLOAT CalcuValue();
		void Set( FLOAT init ){ m_fConstant = init; }
		
		void GetFileBufferInfo( UINT* type, FLOAT* constant, FLOAT* max, FLOAT* min);

		SPDistributionFloat* SpawnInstance();
	protected:
		FLOAT m_fConstant;
	};

	//----------------------------------------------------------
	class DLL_EXPORT SPDistributionFloatUniform : public SPDistributionFloat
	{
	public:
		SPDistributionFloatUniform( FLOAT max, FLOAT min );
		virtual FLOAT CalcuValue();
		void Set( FLOAT fMax, FLOAT fMin ){ m_fMax = fMax; m_fMin = fMin; }
		
		void GetFileBufferInfo( UINT* type, FLOAT* constant, FLOAT* max, FLOAT* min);

		SPDistributionFloat* SpawnInstance();
	protected:
		FLOAT m_fMax;
		FLOAT m_fMin;
	};

	//----------------------------------------------------------
	class DLL_EXPORT SPDistributionFloatCurve : public SPDistributionFloat
	{

	};

	//----------------------------------------------------------
	class DLL_EXPORT SPDistributionFloatNoise : public SPDistributionFloat
	{

	};


	//----------------------------------------------------------
	class DLL_EXPORT SPRawDistributionFloat
	{
	public:
		SPRawDistributionFloat();
		SPRawDistributionFloat( SPRawDistributionFloat* archetype );
		~SPRawDistributionFloat();

		FLOAT CalcValue()
		{
			return m_pDFx->CalcuValue();
		}

		void SafeGet( SPDistributionFloat** px );
		void SafeSet( SPDistributionFloat* px );

		void GetFileBufferInfo( UINT* type, FLOAT* constant, FLOAT* max, FLOAT* min );
		void InitByFileBufferInfo( UINT type, FLOAT constant, FLOAT max, FLOAT min );
	protected:
		SPDistributionFloat* m_pDFx;
	};


	//----------------------------------------------------------
	class DLL_EXPORT SPRawDistributionVector
	{
	public:
		SPRawDistributionVector();
		SPRawDistributionVector( SPRawDistributionVector* archetype );
		~SPRawDistributionVector();

		XMVECTOR CalcValue()
		{
			return XMVectorSet( m_pDFx->CalcuValue(), m_pDFy->CalcuValue(), m_pDFz->CalcuValue(), 0.0f );
		}
		
		void SafeGet( SPDistributionFloat** ppx, SPDistributionFloat** ppy, SPDistributionFloat** ppz );
		void SafeSet( SPDistributionFloat* px, SPDistributionFloat* py, SPDistributionFloat* pz );

		void GetFileBufferInfo( UINT* typex, FLOAT* constantx, FLOAT* maxx, FLOAT* minx, 
			UINT* typey, FLOAT* constanty, FLOAT* maxy, FLOAT* miny, 
			UINT* typez, FLOAT* constantz, FLOAT* maxz, FLOAT* minz );
		void InitByFileBufferInfo(	UINT typex, FLOAT constantx, FLOAT maxx, FLOAT minx, 
			UINT typey, FLOAT constanty, FLOAT maxy, FLOAT miny, 
			UINT typez, FLOAT constantz, FLOAT maxz, FLOAT minz );

	protected:
		SPDistributionFloat* m_pDFx;
		SPDistributionFloat* m_pDFy;
		SPDistributionFloat* m_pDFz;
	};
	//----------------------------------------------------------------
}

///----------------------------------------------------------------
//
///----------------------------------------------------------------